suite("document-sync", function () {
    "use strict";

    require("./global-imports");
    var DocumentSync = require("./document-sync");
    var assert = require("assert");

    test("saves on document change", function () {
        var EventBus = require("./event-bus");

        var document = new EventBus;
        document.id = "doc";
        document.version = 42;
        var testData = {data: "test-data"};
        document.toJson = function () {
            return testData;
        };
        var storage = {
            setItem: function (key, item) {
                storage[key] = item;
            },
            getItem: function (key) {
                return storage[key];
            }
        };
        var sync = new DocumentSync(document, storage);

        document.version = 45;
        document.trigger("change");
        assert(sync.version === document.version);
        assert(JSON.parse(storage.getItem(sync.storagePath())).data === testData.data);
    });

    test("loads on storage change", function () {
        var EventBus = require("./event-bus");
        var saved = {
            addEventListener: window.addEventListener
        };
        var storageHandler = null;
        window.addEventListener = function (_, handler) {
            storageHandler = handler;
        };

        var testData = {
            version: 45,
            data: "test-data"
        };
        var called = false;
        var document = Object.assign({
            id: 36,
            version: 27,
            fromJson: function (json) {
                called = true;
                assert(json.data === testData.data, "right data");
            }
        }, new EventBus);

        var storage = {
            setItem: function (key, item) {
                storage[key] = item;
                if (storageHandler) {
                    storageHandler();
                }
            },
            getItem: function (key) {
                return storage[key];
            }
        };

        var sync = new DocumentSync(document, storage);
        storage.setItem(sync.storagePath(), JSON.stringify(testData));
        assert(called, "fromJson called");

        window.addEventListener = saved.addEventListener;
    });

    test("doesn't save when loading", function () {
        var EventBus = require("./event-bus");

        var document = new EventBus;
        document.version = 0;
        document.fromJson = function () {
            document.trigger("change");
        };

        var storage = {
            getItem: function () {
                return JSON.stringify({version: 1});
            },

            setItem: function () {
                assert(false);
            }
        };

        var sync = new DocumentSync(document, storage);
        sync.load();
    });

    test("doesn't load when stored version is smaller than current", function () {
        var EventBus = require("./event-bus");
        var document = new EventBus;
        document.version = 36;
        document.fromJson = function () {
            assert(false);
        };

        var storage = {
            getItem: function () {
                return JSON.stringify({version: 27});
            }
        };

        var sync = new DocumentSync(document, storage);
        sync.load();
    });

    test("doesn't save when document version is smaller than current", function () {
        var EventBus = require("./event-bus");
        var document = new EventBus;
        document.version = 27;

        var storage = {
            setItem: function () {
                assert(false);
            }
        };

        var sync = new DocumentSync(document, storage);
        document.version = 18;
        document.trigger("change");
    });

    test("doesn't save when document version is smaller than stored", function () {
        var EventBus = require("./event-bus");
        var document = new EventBus;
        document.version = 27;

        var storage = {
            getItem: function () {
                return JSON.stringify({version: 45});
            },

            setItem: function () {
                assert(false);
            }
        };

        var sync = new DocumentSync(document, storage);
        document.version = 36;
        document.trigger("change");
    });

    test("returns the document storage paths", function () {
        var storage = {
            length: 4,
            key: function (i) {
                switch (i) {
                case 0: return "document-editor/1";
                case 1: return "something";
                case 2: return "document-editor/something";
                case 3: return "document-editor/2";
                }
            }
        };

        var ids = DocumentSync.list(storage);
        assert(ids.length === 2, "length");
        assert(ids[0] === 1, "first id");
        assert(ids[1] === 2, "second is");
    });
});
